/*
 ============================================================================
 文件名    : Engine.cpp
 描述     : CEngine类的实现.
 ============================================================================
 */

// 引用
#include "Engine.h"

// 初始化静态成员
CEngine* CEngine::iEngine = NULL;

// ============================ 成员函数 ===============================

// ---------------------------------------------------------
// CEngine::CEngine
// 构造函数.
// ---------------------------------------------------------
//
CEngine::CEngine():CActive( EPriorityStandard ),iSpeedTune(0)
	{
	iGameState = KGameNew;
	iBall = NULL;
	iLine = iLeft = iRight = NULL;
	iGameRoom = TRect( TPoint(0,0), TPoint(300,600) );
	}

// ---------------------------------------------------------
// CEngine::CEngine
// 析构函数.
// ---------------------------------------------------------
//
CEngine::~CEngine()
	{
	Cancel();
	DetachObservers();
	delete iBall;
	iBall = NULL;
	delete iLine;
	iLine = NULL;
	delete iLeft;
	iLeft = NULL;
	delete iRight;
	iRight = NULL;
	}

// ---------------------------------------------------------
// CEngine::ConstructL
// 两段构造函数.
// ---------------------------------------------------------
//
void CEngine::ConstructL()
	{
	iBall = CWoodenBall::NewL();
	iBall->SetPos( TRealPoint( 150,500) );
	iLine = CLine::NewL( TRealPoint(0, 10 ), 
			TRealPoint( iGameRoom.iBr.iX, 10 ) );
	iLeft = CLine::NewL( TRealPoint(0,iGameRoom.Height()),
			TRealPoint( 0, 0 ));
	iRight = CLine::NewL( TRealPoint( iGameRoom.Width(), iGameRoom.Height() ),
			TRealPoint( iGameRoom.Width(), 0 ));
			
	CActiveScheduler::Add( this );
	}

// ---------------------------------------------------------
// CEngine::Instance
// 返回CEngine对像的指针
// ---------------------------------------------------------
//
CEngine* CEngine::Instance()
	{
	if( !iEngine )
		{
		iEngine = new (ELeave)CEngine;
		CleanupStack::PushL( iEngine );
		iEngine->ConstructL();
		CleanupStack::Pop();
		}
	return iEngine;
	}

// ---------------------------------------------------------
// CEngine::Initialize
// 初始化引擎状态
// ---------------------------------------------------------
//
void CEngine::Initialize()
	{
	iGameState = KGameStarted;
	}

// ---------------------------------------------------------
// CEngine::PauseOrResume
// 暂停或是恢复运行
// ---------------------------------------------------------
//
void CEngine::PauseOrResume()
	{
	if( iGameState == KGameStarted )
		{
		iGameState = KGamePaused;
		}
	else if( iGameState == KGamePaused )
		{
		iGameState = KGameStarted;
		TRequestStatus* status = &iStatus;
		User::RequestComplete( status, KErrNone );
		SetActive();
		}
	}

// ---------------------------------------------------------
// CEngine::Next
// 从运行状态进入下一状态
// ---------------------------------------------------------
//
void CEngine::Next()
	{
	iSpeedTune ++;
	if( iGameState != KGamePaused && iSpeedTune == 1 )
		{
		iSpeedTune = 0;
		if( !iBall->Hit( iRight ) && !iBall->Hit( iLeft ) && iBall->Hit( iLine ) )
			{
			for( TInt i = 0; i < iObservers.Count(); i++ )
			    {
			    iObservers[i]->BallHitsLine( this );
			    }
			}
		iBall->Move();
		iGameState = KGameStarted;		
		for( TInt i = 0; i < iObservers.Count(); ++ i )
		    {
		    iObservers[i]->GameChanged( this );
		    }
		}
	TRequestStatus* status = &iStatus;
	User::RequestComplete( status, KErrNone );
	SetActive();		
	}

// ---------------------------------------------------------
// CEngine::RunL
// 从运行状态进入下一状态
// ---------------------------------------------------------
//
void CEngine::RunL()
	{
	if( !GameOver() && iGameState != KGamePaused )
		{
		Next();
		}
	}

// ---------------------------------------------------------
// CEngine::DoCancel
// 取消操作并停止引擎
// ---------------------------------------------------------
//
void CEngine::DoCancel()
	{
	}

// ---------------------------------------------------------
// CEngine::RunError
// 引擎错误处理
// ---------------------------------------------------------
//
TInt CEngine::RunError( TInt /*aError*/ )
	{
	return 0;
	}

// ---------------------------------------------------------
// CEngine::GetBall
// 返回游戏小球
// ---------------------------------------------------------
//
CBall* CEngine::GetBall()
	{
	return iBall;
	}

// ---------------------------------------------------------
// CEngine::GetLine
// 返回最近一次用户画的线
// ---------------------------------------------------------
//
CLine* CEngine::GetLine()
	{
	return iLine;
	}

// ---------------------------------------------------------
// CEngine::AttachObserver
// 持载观察者并通知观察者当前游戏状态
// ---------------------------------------------------------
//
void CEngine::AttachObserver( MGameObserver* aObserver )
	{
	iObservers.Append( aObserver );
	aObserver->GameChanged( this );
	}

// ---------------------------------------------------------
// CEngine::DetachObservers
// 移除所有观察者
// ---------------------------------------------------------
//
void CEngine::DetachObservers()
	{
	iObservers.Close();
	}

// ---------------------------------------------------------
// CEngine::Destroy
// 销毁引擎对象
// ---------------------------------------------------------
//
void CEngine::Destroy()
	{
	delete iEngine;
	iEngine = NULL;
	}

// ---------------------------------------------------------
// CEngine::GameOver
// 判断游戏结束
// ---------------------------------------------------------
//
TBool CEngine::GameOver()
	{
	if( iBall->GetPos().iY + iBall->GetRad() <= 0.0f )
		{
		iGameState = KGameOver;
		iBall->SetPos( TRealPoint(-24.0f,-24.0f) );
		iLine->SetStart( TPoint( -1,-1) );
		iLine->SetEnd( TPoint( 0, 0) );
		for( TInt i = 0; i < iObservers.Count(); ++i )
		    {
		    iObservers[i]->GameOver( this );
		    }
		return ETrue;
		}
	return EFalse;
	}

// ---------------------------------------------------------
// CEngine::GetGameRoom
// 返回游戏空间
// ---------------------------------------------------------
//
TRect CEngine::GetGameRoom()
	{
	return iGameRoom;
	}

// 文件结束
